from uuid import uuid4
import json
import os
from datetime import datetime

from rest_framework import serializers

from .models import Gateway, Sensor
from apps.scripts.models import Scripts
from util.exception import ValidationError
from django.conf import settings


class GatewaySerializer(serializers.ModelSerializer):
    model_number = serializers.CharField(max_length=20, allow_null=False)
    mcu_id = serializers.CharField(max_length=100, allow_null=False)
    gateway_id = serializers.IntegerField(allow_null=False)
    is_tac31 = serializers.BooleanField(allow_null=False)

    def validate_gateway_id(self, obj):
        gateway = Gateway.objects.filter(gateway_id=obj).first()
        if gateway:
            raise ValidationError(30003)
        return obj

    class Meta:
        model = Gateway
        fields = ["model_number", "mcu_id", "gateway_id", "is_tac31"]

    def create(self, data):
        id = str(uuid4()).replace("-", "")
        data["key"] = id
        data["client_id"] = "".join([settings.ID_HEAD, str(data.get("gateway_id")), settings.ID_END])
        Gateway.objects.create(**data)
        return id


class GatewayListCheckSerializer(serializers.ModelSerializer):
    gateway_id = serializers.CharField(max_length=20, allow_null=True, allow_blank=True)
    model_number = serializers.CharField(max_length=100, allow_null=True, allow_blank=True)
    state = serializers.BooleanField(allow_null=True)
    active_state = serializers.IntegerField(allow_null=True)
    script_id = serializers.CharField(max_length=32, allow_null=True, allow_blank=True)
    order = serializers.IntegerField(allow_null=True, default=-1)
    is_tac31 = serializers.BooleanField(allow_null=True)
    sim_number = serializers.CharField(max_length=32, allow_null=True, allow_blank=True)

    class Meta:
        model = Gateway
        fields = ["gateway_id", "model_number", "state", "active_state", "script_id", "order", "is_tac31", "sim_number"]


class GatewayListSerializer(serializers.ModelSerializer):
    class Meta:
        model = Gateway
        fields = ["gateway_id", "client_id", "name", "model_number", "state", "active_state", "script_name",
                  "script_id",
                  "create_date", "key", "mcu_id", "is_tac31", "last_log_in", "last_exit_out", "singal", "sim_status",
                  "sim_number"]


class GatewayActiveSerializer(serializers.ModelSerializer):
    active_state = serializers.BooleanField(allow_null=False)
    name = serializers.CharField(max_length=100, allow_null=False)
    script_id = serializers.CharField(max_length=32, allow_null=True)
    key = serializers.CharField(max_length=32, allow_null=False)

    class Meta:
        model = Gateway
        fields = ["name", "active_state", "script_id", "key"]

    def validate_name(self, obj):
        gateway = Gateway.objects.filter(name=obj).first()
        if gateway:
            raise ValidationError(30001)
        return obj

    def create(self, data):
        script_id = data.get("script_id")
        key = data.get("key")
        sc = Scripts.objects.filter(id=script_id).first()
        if not sc:
            raise ValidationError(50003)
        try:
            data["client_id"] = "".join([settings.ID_HEAD, str(data.get("gateway_id")), settings.ID_END])
            instance = Gateway.objects.filter(gateway_id=key).first()
            instance.script_id = script_id
            instance.script_name = sc.name
            instance.name = data["name"]
            instance.state = 1
            if instance.is_tac31:
                instance.active_state = 1
            else:
                instance.active_state = 0
            instance.file_path = ""
            instance.is_delete = False
            instance.update_date = datetime.now()
            instance.save()
            return instance
        except Exception as e:
            raise e


class GatewayUpdateSerializer(serializers.ModelSerializer):
    key = serializers.CharField(max_length=32, allow_null=False)
    update_date = serializers.DateTimeField(allow_null=True)
    is_delete = serializers.BooleanField(allow_null=False)
    script_id = serializers.CharField(max_length=32, allow_null=False)

    class Meta:
        model = Gateway
        fields = ["key", "update_date", "is_delete", "script_id"]

    def validate_name(self, obj):
        gateway = Gateway.objects.filter(name=obj).first()
        if gateway:
            raise ValidationError(30001)
        return obj

    def update(self, instance, data):
        script_name = data.get("script_id")
        sc = Scripts.objects.filter(name=script_name).first()
        if not sc:
            raise ValidationError(50003)
        instance.script_name = sc.name
        instance.update_date = data["update_date"]
        instance.is_delete = data["is_delete"]
        instance.script_id = sc.id
        instance.save()
        self.__delete_file(instance)

    def __delete_file(self, instance):
        gate_id = instance.key
        file_path = "".join([settings.DEPLOY_FILE_DIR, gate_id])
        if os.path.isfile(file_path):
            os.remove(file_path)


class GatewaySIMNumberSerializer(serializers.ModelSerializer):
    key = serializers.CharField(max_length=32, allow_null=False)
    sim_number = serializers.CharField(max_length=30, allow_null=False)

    class Meta:
        model = Gateway
        fields = ["key", "sim_number"]

    def update(self, instance, data):
        instance.sim_number = data["sim_number"]
        instance.save()
